package scheduler

import (
	"context"
	"sync"

	"github.com/google/uuid"
	"github.com/mars/pkg/loggers"
	"go.uber.org/zap"
)

const (
	traceIdKey = "traceId"
)

type IScheduler interface {
	// 执行定时任务
	Execute()

	// 停止定时任务
	Shutdown()
}

type Scheduler struct {
	wait     sync.WaitGroup
	cancelFn context.CancelFunc
	ctx      context.Context
	jobs     []Job
}

func NewScheduler(ctx context.Context, jobs []Job) *Scheduler {
	var sc Scheduler

	sc.ctx, sc.cancelFn = context.WithCancel(ctx)

	return &sc
}

func (s *Scheduler) Execute() {
	for _, job := range s.jobs {
		s.wait.Add(1)
		go func(j Job) {
			defer s.wait.Done()
			for {
				select {
				case <-j.Timer().C:
					fields := []zap.Field{zap.String(traceIdKey, uuid.New().String())}
					loggers.Infofw(fields, "start execute task %s", j.Name())
					if err := j.Do(); err != nil {
						loggers.Errorfw(fields, "execute task failed: %v", err)
					}
				case <-s.ctx.Done():
					return
				}
			}
		}(job)
	}
}

func (s *Scheduler) Shutdown() {
	s.cancelFn()
	s.wait.Wait()
	loggers.Info("scheduler stop finished....")
}
